package com.traffic.managent.config;

import org.apache.log4j.Logger;
import org.beetl.core.GroupTemplate;
import org.beetl.ext.jfinal.BeetlRenderFactory;

import com.cxhome.cxinfox.cxuser.CxUserInterceptor;
import com.jfinal.config.Constants;
import com.jfinal.config.Handlers;
import com.jfinal.config.Interceptors;
import com.jfinal.config.JFinalConfig;
import com.jfinal.config.Plugins;
import com.jfinal.config.Routes;
import com.jfinal.ext.handler.ContextPathHandler;
import com.jfinal.ext.interceptor.SessionInViewInterceptor;
import com.jfinal.kit.PathKit;
import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory;
import com.jfinal.plugin.activerecord.dialect.OracleDialect;
import com.jfinal.plugin.activerecord.dialect.PostgreSqlDialect;
import com.jfinal.plugin.activerecord.dialect.Sqlite3Dialect;
import com.jfinal.plugin.c3p0.C3p0Plugin;
import com.jfinal.render.ViewType;
import com.traffic.managent.annotation.AutoBindModels;
import com.traffic.managent.annotation.AutoBindRoutes;
import com.traffic.managent.beetl.BeeltFunctions;
import com.traffic.managent.beetl.BeetlStrFunctions;
import com.traffic.managent.handler.BasePathHandler;
import com.traffic.managent.handler.CurrentPathHandler;
import com.traffic.managent.handler.HtmlHandler;
import com.traffic.managent.interceptor.CxhomeInterceptor;
import com.traffic.managent.interceptor.ExceptionInterceptor;
import com.traffic.managent.interceptor.PageViewInterceptor;
import com.traffic.managent.interceptor.SessionAttrInterceptor;
import com.traffic.managent.interceptor.UpdateCacheInterceptor;
import com.traffic.managent.interceptor.UserKeyInterceptor;
import com.traffic.managent.jedis.RedisPlugin;
import com.traffic.managent.plugin.ParamInitThread;
import com.traffic.managent.plugin.RedisOrderQueuePlugin;
import com.traffic.managent.serializable.FSTSerializer;
import com.traffic.managent.serializable.SerializerManage;
import com.traffic.managent.util.StringUtils;

/**
 * Jfinal API 引导式配置
 */
public class CxhomeConfig extends JFinalConfig {

	private static Logger log = Logger.getLogger(CxhomeConfig.class);

	/**
	 * 配置常量
	 */
	public void configConstant(Constants me) {
		me.setDevMode(true);
		me.setViewType(ViewType.JSP); // 设置视图类型为Jsp，否则默认为FreeMarker
		me.setBaseViewPath("/pages");
//		me.setLogFactory(new Log4jLogFactory());
		me.setError401View(CxHomeproperties.getStr("PAGES.401"));
		me.setError403View(CxHomeproperties.getStr("PAGES.403"));
		me.setError404View(CxHomeproperties.getStr("PAGES.404"));
		me.setError500View(CxHomeproperties.getStr("PAGES.500"));

		// 开启日志
//		SqlReporter.setLog(true);

		me.setMainRenderFactory(new BeetlRenderFactory());

		// 获取GroupTemplate ,可以设置共享变量等操作
		GroupTemplate groupTemplate = BeetlRenderFactory.groupTemplate;
		/**
		 * 页面可以通过 ${strutil.subStringTo(item.content, 0, 15)}... 方式条用该工具方法
		 */
		groupTemplate.registerFunctionPackage("strutil", BeetlStrFunctions.class);
		groupTemplate.registerFunctionPackage("flyfox", BeeltFunctions.class);
	}


	/**
	 * 配置路由
	 */
	public void configRoute(Routes me) {
//		me.setBaseViewPath("/pages");
		// 自动绑定
		// 1.如果没用加入注解，必须以Controller结尾,自动截取前半部分为key
		// 2.加入ControllerBind的 获取 key
		me.add(new AutoBindRoutes());

	}

	/**
	 * 配置插件
	 */
	public void configPlugin(Plugins me) {

		// RedisPlugin 加载redis订购插件
		RedisPlugin redisPlugin = new RedisPlugin(CxHomeproperties.getStr("redis.orderPlugin"),
				CxHomeproperties.getStr("redis.host"), CxHomeproperties.getToInt("redis.port"),
				CxHomeproperties.getToInt("redis.maxWait"), CxHomeproperties.getStr("redis.password"), 15);
		redisPlugin.getJedisPoolConfig().setMaxIdle(20);
		redisPlugin.getJedisPoolConfig().setMaxTotal(20);
		redisPlugin.getJedisPoolConfig().setMaxWaitMillis(200000);
		me.add(redisPlugin);
		
		// RedisPlugin 加载redis系统参数插件
		RedisPlugin redisSysPlugin = new RedisPlugin(CxHomeproperties.getStr("redis.sysPlugin"), CxHomeproperties.getStr("redis.host"),
				CxHomeproperties.getToInt("redis.port"), CxHomeproperties.getToInt("redis.maxWait"),
				CxHomeproperties.getStr("redis.password"), 14);
		redisSysPlugin.getJedisPoolConfig().setMaxIdle(40);
		redisSysPlugin.getJedisPoolConfig().setMaxTotal(40);
		me.add(redisSysPlugin);
		
		// 配置C3p0数据库连接池插件
		C3p0Plugin c3p0Plugin = null;

		String db_type = CxHomeproperties.getStr("db_type") + ".";

		String webRoot = PathKit.getWebRootPath();
		String DBPath = webRoot + "\\WEB-INF\\";
		DBPath = StringUtils.replace(DBPath, "\\", "/");
		String jdbcUrl = CxHomeproperties.getStr(db_type + "jdbcUrl");
		if (db_type.startsWith("sqlite")) {
			jdbcUrl = StringUtils.replaceOnce(jdbcUrl, "{webroot}", DBPath);
		}

		c3p0Plugin = new C3p0Plugin( //
				jdbcUrl, CxHomeproperties.getStr(db_type + "user"), //
				CxHomeproperties.getStr(db_type + "password").trim(), //
				CxHomeproperties.getStr(db_type + "driverClass"));

		me.add(c3p0Plugin);

		// 配置ActiveRecord插件
		ActiveRecordPlugin arp = new ActiveRecordPlugin(c3p0Plugin);
//		arp.setContainerFactory(new CaseInsensitiveContainerFactory(false));
		me.add(arp);
		
			arp.setShowSql(true);

		// 数据库类型
		if (db_type.startsWith("postgre")) {
			arp.setDialect(new PostgreSqlDialect());
		} else if (db_type.startsWith("sqlite")) {
			arp.setDialect(new Sqlite3Dialect());
		} else if (db_type.startsWith("oracle")) {
			arp.setDialect(new OracleDialect());
			arp.setContainerFactory(new CaseInsensitiveContainerFactory(true));
		}

		new AutoBindModels(arp);
		// RedisOrderQueuePlugin 加载redis队列插件
//		RedisOrderQueuePlugin queuePlugin = new RedisOrderQueuePlugin();
//		me.add(queuePlugin);
	}

	/**
	 * 配置全局拦截器
	 */
	public void configInterceptor(Interceptors me) {
		// session model转换

		// 异常拦截器，跳转到500页面
		me.add(new ExceptionInterceptor());
		// session model转换
		me.add(new SessionInViewInterceptor());
		// 设置session属性
		me.add(new SessionAttrInterceptor());
		// 公共拦截器
		me.add(new CxhomeInterceptor());
		// 用户Key设置
		me.add(new UserKeyInterceptor());
		// page view 统计
		me.add(new PageViewInterceptor());
		// 缓存更新
		me.add(new UpdateCacheInterceptor());
		// 用户认证
		me.add(new CxUserInterceptor());
	}

	/**
	 * 配置处理器
	 */
	public void configHandler(Handlers me) {
		// Beelt
		me.add(new HtmlHandler());

		// 全路径获取
		me.add(new BasePathHandler(CxHomeproperties.getStr("PATH.BASE_PATH")));
		// 根目录获取
		me.add(new ContextPathHandler(CxHomeproperties.getStr("PATH.CONTEXT_PATH")));
		// 当前获取
		me.add(new CurrentPathHandler(CxHomeproperties.getStr("PATH.CURRENT_PATH")));

	}

	public void afterJFinalStart() {

		super.afterJFinalStart();

		// 初始化Cache为fst序列化
		SerializerManage.add("fst", new FSTSerializer());

		// 设置序列化工具
		String defaultKey = CxHomeproperties.getStr("CACHE.SERIALIZER.DEFAULT");
		defaultKey = StringUtils.isEmpty(defaultKey) ? "java" : defaultKey;
		SerializerManage.setDefaultKey(defaultKey);

		// 设置队列
		new ParamInitThread().start();
		System.out.println("##################################");
		System.out.println("############系统启动完成##########");
		System.out.println("##################################");
	}

	/**
	 * 系统关闭前调用
	 */
	public void beforeJFinalStop() {
		super.beforeJFinalStop();

		// 关闭模板
		BeetlRenderFactory.groupTemplate.close();

		System.out.println("##################################");
		System.out.println("############系统停止完成##########");
		System.out.println("##################################");
	}


}
